<template>
  <div class="menu-management">
    <div class="menu-container">
      <!-- 左侧菜单树 -->
      <div class="menu-tree-panel">
        <div class="panel-header">
          <span class="header-title">菜单结构</span>
          <el-button type="primary" size="small" @click="handleAddMenu" style="font-size: 12px; padding: 4px 8px;">
            新增菜单
          </el-button>
        </div>
        <div class="tree-content">
          <el-tree ref="menuTreeRef" :data="menuTreeData" :props="treeProps" node-key="id" :default-expand-all="false"
            :highlight-current="true" @node-click="handleNodeClick" class="menu-tree">
            <template #default="{ node, data }">
              <div class="tree-node">
                <div class="node-content">
                  <span class="node-label">{{ data.menu_name }}</span>
                  <span v-if="data.status === '0'" class="status-disabled">[已禁用]</span>
                </div>
                <div class="node-actions">
                  <el-button type="text" size="small" @click.stop="handleEditMenu(data)" class="action-btn" title="编辑">
                    <el-icon>
                      <Edit />
                    </el-icon>
                  </el-button>
                  <el-button type="text" size="small" @click.stop="handleToggleMenu(data)" class="action-btn"
                    :title="data.status === 1 ? '禁用' : '启用'">
                    <el-icon>
                      <Switch />
                    </el-icon>
                  </el-button>
                  <el-button type="text" size="small" @click.stop="handleDeleteMenu(data)" class="action-btn delete-btn"
                    title="删除">
                    <el-icon>
                      <Delete />
                    </el-icon>
                  </el-button>
                </div>
              </div>
            </template>
          </el-tree>
          <div v-if="menuTreeData.length === 0 && !loading" style="text-align: center; color: #999; padding: 40px;">
            暂无菜单数据
          </div>
        </div>
      </div>

      <!-- 右侧功能表格 -->
      <div class="function-table-panel">
        <div class="panel-header">
          <span class="header-title">{{ selectedMenuName || '我的客户' }}</span>
          <el-button type="primary" @click="handleAddFunction">
            新增功能
          </el-button>
        </div>
        <div class="table-content">
          <div class="common-table-wrapper">
            <table class="common-table">
              <thead>
                <tr>
                  <th style="width: 80px;">序号</th>
                  <th style="min-width: 150px;">功能名称</th>
                  <th style="min-width: 200px;">功能路径</th>
                  <th style="width: 120px;">操作</th>
                </tr>
              </thead>
              <tbody>
                <tr v-for="(item, index) in tableData" :key="item.id || index">
                  <td>{{ item.orderid }}</td>
                  <td>{{ item.menu_name }}</td>
                  <td>{{ item.menu_url }}</td>
                  <td>
                    <el-button type="text" size="small" @click="handleEditFunction(item)"
                      class="table-action-btn edit-btn">
                      <el-icon>
                        <Edit />
                      </el-icon>
                    </el-button>
                    <el-button type="text" size="small" @click="handleDeleteFunction(item)"
                      class="table-action-btn delete-btn">
                      <el-icon>
                        <Delete />
                      </el-icon>
                    </el-button>
                  </td>
                </tr>
                <tr v-if="tableData.length === 0 && !tableLoading">
                  <td colspan="4" style="text-align: center; color: #999; padding: 40px;">
                    暂无数据
                  </td>
                </tr>
              </tbody>
            </table>
          </div>
        </div>
      </div>
    </div>

    <!-- 新增/编辑菜单对话框 -->
    <el-dialog v-model="menuDialogVisible" :title="menuDialogTitle" width="500px" @close="resetMenuForm">
      <el-form ref="menuFormRef" :model="menuForm" :rules="menuRules" label-width="100px">
        <el-form-item label="菜单名称" prop="menu_name">
          <el-input v-model="menuForm.menu_name" placeholder="请输入菜单名称" />
        </el-form-item>
        <el-form-item label="菜单路径" prop="menu_url">
          <el-input v-model="menuForm.menu_url" placeholder="请输入菜单路径" />
        </el-form-item>
        <el-form-item label="父级菜单" prop="pid">
          <el-select v-model="menuForm.pid" filterable placeholder="请选择父级菜单">
            <el-option label="顶级菜单" value="0" />
            <el-option v-for="menu in flatMenuList" :key="menu.id" :label="menu.menu_name" :value="menu.id" />
          </el-select>
        </el-form-item>
        <el-form-item label="菜单图标" prop="menu_icon">
          <el-input v-model="menuForm.menu_icon" placeholder="请输入图标类名" />
        </el-form-item>
        <el-form-item label="排序" prop="orderid">
          <el-input-number v-model="menuForm.orderid" :min="1" />
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="menuDialogVisible = false">取消</el-button>
          <el-button type="primary" @click="handleMenuSubmit">确定</el-button>
        </span>
      </template>
    </el-dialog>

    <!-- 新增/编辑功能对话框 -->
    <el-dialog v-model="functionDialogVisible" :title="functionDialogTitle" width="500px" @close="resetFunctionForm">
      <el-form ref="functionFormRef" :model="functionForm" :rules="functionRules" label-width="100px">
        <el-form-item label="功能名称" prop="menu_name">
          <el-input v-model="functionForm.menu_name" placeholder="请输入功能名称" />
        </el-form-item>
        <el-form-item label="功能路径" prop="menu_url">
          <el-input v-model="functionForm.menu_url" placeholder="请输入功能路径" />
        </el-form-item>
        <el-form-item label="排序" prop="orderid">
          <el-input-number v-model="functionForm.orderid" :min="1" />
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="functionDialogVisible = false">取消</el-button>
          <el-button type="primary" @click="handleFunctionSubmit">确定</el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>

<script setup>
import { ref, reactive, computed, onMounted } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { Edit, Delete, Switch } from '@element-plus/icons-vue'
import { menuApi } from '@/api/menu'

// 响应式数据
const menuTreeData = ref([])
const tableData = ref([])
const selectedMenuId = ref('')
const selectedMenuName = ref('')
const menuDialogVisible = ref(false)
const functionDialogVisible = ref(false)
const menuFormRef = ref()
const functionFormRef = ref()
const menuTreeRef = ref()
const loading = ref(false)
const tableLoading = ref(false)

// 树形组件配置
const treeProps = {
  children: 'children',
  label: 'menu_name'
}

// 菜单表单
const menuForm = reactive({
  orderid: '0',
  menu_name: '',
  menu_url: '',
  pid: '0',
  menu_icon: ''
})

// 功能表单
const functionForm = reactive({
  id: '',
  menu_name: '',
  menu_url: '',
  orderid: 1
})

// 表单验证规则
const menuRules = {
  menu_name: [
    { required: true, message: '请输入菜单名称', trigger: 'blur' }
  ],
  menu_type: [
    { required: true, message: '请选择菜单类型', trigger: 'change' }
  ]
}

const functionRules = {
  menu_name: [
    { required: true, message: '请输入功能名称', trigger: 'blur' }
  ],
  menu_url: [
    { required: true, message: '请输入功能路径', trigger: 'blur' }
  ]
}

// 计算属性
/**
 * 菜单对话框标题计算属性
 * 根据是否有菜单ID判断是新增还是编辑模式
 * @computed menuDialogTitle
 * @returns {string} 对话框标题
 */
const menuDialogTitle = computed(() => {
  return menuForm.id ? '编辑菜单' : '新增菜单'
})

/**
 * 功能对话框标题计算属性
 * 根据是否有功能ID判断是新增还是编辑模式
 * @computed functionDialogTitle
 * @returns {string} 对话框标题
 */
const functionDialogTitle = computed(() => {
  return functionForm.id ? '编辑功能' : '新增功能'
})

/**
 * 扁平化菜单列表计算属性
 * 将树形菜单结构转换为扁平列表，只包含一级菜单
 * @computed flatMenuList
 * @returns {Array} 扁平化的一级菜单列表
 */
const flatMenuList = computed(() => {
  const result = []

  /**
   * 递归扁平化菜单树
   * @function flatten
   * @param {Array} menus - 菜单数组
   * @returns {void}
   */
  const flatten = (menus) => {
    menus.forEach(menu => {
      if (menu.level === 1) {
        result.push(menu)
      }
      if (menu.children && menu.children.length > 0) {
        flatten(menu.children)
      }
    })
  }

  flatten(menuTreeData.value)
  return result
})

/**
 * 初始化页面数据
 * 页面加载时调用，负责加载菜单树数据
 * @async
 * @function initData
 * @returns {Promise<void>}
 */
const initData = async () => {
  try {
    loading.value = true
    await loadMenuTree()
  } catch (error) {
    console.error('初始化数据失败:', error)
    ElMessage.error('加载菜单数据失败')
  } finally {
    loading.value = false
  }
}

/**
 * 加载菜单树数据
 * 从后端API获取菜单树结构数据，并默认选中第一个菜单
 * @async
 * @function loadMenuTree
 * @returns {Promise<void>}
 * @throws {Error} 当API调用失败时抛出错误
 */
const loadMenuTree = async () => {
  try {
    const response = await menuApi.getMenuTree()
    if (response.status) {
      menuTreeData.value = response.data.menu_list
      // 默认选中第一个菜单
      if (menuTreeData.value.length > 0) {
        const firstMenu = menuTreeData.value[0].children[0]
        await selectMenu(firstMenu)
      }
    } else {
      throw new Error(response.message || '获取菜单数据失败')
    }
  } catch (error) {
    console.error('加载菜单树失败:', error)
    throw error
  }
}

/**
 * 选择菜单并加载对应的功能列表
 * 当用户点击菜单树节点时调用，更新选中状态并加载功能列表
 * @async
 * @function selectMenu
 * @param {Object} menu - 选中的菜单对象
 * @param {string|number} menu.id - 菜单ID
 * @param {string} menu.menu_name - 菜单名称
 * @returns {Promise<void>}
 */
const selectMenu = async (menu) => {
  selectedMenuId.value = menu.id
  selectedMenuName.value = menu.menu_name

  // 设置树形组件的当前选中节点
  setTimeout(() => {
    if (menuTreeRef.value) {
      menuTreeRef.value.setCurrentKey(menu.id)
    }
  }, 100)

  // 加载功能列表
  await loadFunctionList(menu.id)
}

/**
 * 加载功能列表
 * 根据菜单ID加载对应的功能列表数据
 * @async
 * @function loadFunctionList
 * @param {string|number} menuId - 菜单ID
 * @returns {Promise<void>}
 */
const loadFunctionList = async (menuId) => {
  try {
    tableLoading.value = true
    const response = await menuApi.getFunctionList(menuId)
    if (response.status) {
      tableData.value = response.data.list.map((item, index) => ({
        ...item,
        orderid: index + 1
      }))
    } else {
      // 如果没有功能数据，显示空数组
      tableData.value = []
    }
  } catch (error) {
    console.error('加载功能列表失败:', error)
    ElMessage.error('加载功能列表失败')
    tableData.value = []
  } finally {
    tableLoading.value = false
  }
}




/**
 * 处理菜单树节点点击事件
 * 当用户点击菜单树节点时触发，选择对应的菜单
 * @async
 * @function handleNodeClick
 * @param {Object} data - 点击的菜单节点数据
 * @returns {Promise<void>}
 */
const handleNodeClick = async (data) => {
  await selectMenu(data)
}

/**
 * 处理添加菜单操作
 * 重置菜单表单并显示菜单编辑对话框
 * @function handleAddMenu
 * @returns {void}
 */
/**
 * 处理添加菜单操作
 * 重置菜单表单并显示菜单编辑对话框
 * @function handleAddMenu
 * @returns {void}
 */
const handleAddMenu = () => {
  resetMenuForm()
  menuDialogVisible.value = true
}

/**
 * 处理编辑菜单操作
 * 将选中的菜单数据填充到表单中并显示编辑对话框
 * @function handleEditMenu
 * @param {Object} menu - 要编辑的菜单对象
 * @param {string|number} menu.id - 菜单ID
 * @param {string} menu.menu_name - 菜单名称
 * @param {string} menu.menu_url - 菜单路径
 * @param {string} menu.menu_icon - 菜单图标
 * @param {number} menu.orderid - 排序号
 * @returns {void}
 */
const handleEditMenu = (menu) => {
  Object.assign(menuForm, menu)
  menuDialogVisible.value = true
}

/**
 * 处理菜单状态切换操作
 * 切换菜单的启用/禁用状态，需要用户确认
 * @async
 * @function handleToggleMenu
 * @param {Object} menu - 要切换状态的菜单对象
 * @param {string|number} menu.id - 菜单ID
 * @param {string} menu.menu_name - 菜单名称
 * @param {string} menu.status - 当前状态 ('1':启用, '0':禁用)
 * @returns {Promise<void>}
 */
const handleToggleMenu = async (menu) => {
  const action = menu.status === '1' ? '禁用' : '启用'
  const newStatus = menu.status === '1' ? '0' : '1'

  try {
    await ElMessageBox.confirm(
      `确定要${action}菜单"${menu.menu_name}"吗？`,
      '提示',
      {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning',
      }
    )

    // 调用切换状态接口
    await menuApi.toggleMenuStatus(menu.id, newStatus)
    menu.status = newStatus
    ElMessage.success(`${action}成功`)
  } catch (error) {
    if (error !== 'cancel') {
      console.error('切换菜单状态失败:', error)
      ElMessage.error(`${action}失败`)
    } else {
      ElMessage.info(`已取消${action}`)
    }
  }
}

/**
 * 处理删除菜单操作
 * 删除指定的菜单，需要用户确认，删除成功后重新加载菜单树
 * @async
 * @function handleDeleteMenu
 * @param {Object} menu - 要删除的菜单对象
 * @param {string|number} menu.id - 菜单ID
 * @param {string} menu.menu_name - 菜单名称
 * @returns {Promise<void>}
 */
const handleDeleteMenu = async (menu) => {
  try {
    await ElMessageBox.confirm(
      `确定要删除菜单"${menu.menu_name}"吗？`,
      '提示',
      {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning',
      }
    )

    // 调用删除接口
    await menuApi.deleteMenu(menu.id)
    ElMessage.success('删除成功')

    // 重新加载菜单树
    await loadMenuTree()
  } catch (error) {
    if (error !== 'cancel') {
      console.error('删除菜单失败:', error)
      ElMessage.error('删除失败')
    } else {
      ElMessage.info('已取消删除')
    }
  }
}

/**
 * 处理添加功能操作
 * 重置功能表单并显示功能编辑对话框
 * @function handleAddFunction
 * @returns {void}
 */
const handleAddFunction = () => {
  resetFunctionForm()
  functionDialogVisible.value = true
}

/**
 * 处理编辑功能操作
 * 将选中的功能数据填充到表单中并显示编辑对话框
 * @function handleEditFunction
 * @param {Object} func - 要编辑的功能对象
 * @param {string|number} func.id - 功能ID
 * @param {string} func.menu_name - 功能名称
 * @param {string} func.menu_url - 功能路径
 * @param {string} func.menu_icon - 功能图标
 * @param {number} func.orderid - 排序号
 * @returns {void}
 */
const handleEditFunction = (func) => {
  Object.assign(functionForm, func)
  functionDialogVisible.value = true
}

/**
 * 处理删除功能操作
 * 删除指定的功能，需要用户确认，删除成功后重新加载功能列表
 * @async
 * @function handleDeleteFunction
 * @param {Object} func - 要删除的功能对象
 * @param {string|number} func.id - 功能ID
 * @param {string} func.menu_name - 功能名称
 * @returns {Promise<void>}
 */
const handleDeleteFunction = async (func) => {
  try {
    await ElMessageBox.confirm(
      `确定要删除功能"${func.menu_name}"吗？`,
      '提示',
      {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning',
      }
    )

    // 调用删除接口
    await menuApi.deleteFunction(func.id)
    ElMessage.success('删除成功')

    // 重新加载功能列表
    await loadFunctionList(selectedMenuId.value)
  } catch (error) {
    if (error !== 'cancel') {
      console.error('删除功能失败:', error)
      ElMessage.error('删除失败')
    } else {
      ElMessage.info('已取消删除')
    }
  }
}

/**
 * 处理菜单表单提交
 * 验证表单数据并提交到后端，支持新增和编辑两种模式
 * @async
 * @function handleMenuSubmit
 * @returns {Promise<void>}
 */
const handleMenuSubmit = async () => {
  try {
    await menuFormRef.value.validate()

    const isEdit = !!menuForm.id
    const apiCall = isEdit
      ? menuApi.updateMenu(menuForm)
      : menuApi.createMenu(menuForm)

    await apiCall
    ElMessage.success(isEdit ? '编辑成功' : '新增成功')
    menuDialogVisible.value = false

    // 重新加载菜单树
    await loadMenuTree()
  } catch (error) {
    if (error.message) {
      ElMessage.error(error.message || '操作失败')
    } else {
      console.error('表单验证失败:', error)
    }
  }
}

/**
 * 处理功能表单提交
 * 验证表单数据并提交到后端，支持新增和编辑两种模式
 * @async
 * @function handleFunctionSubmit
 * @returns {Promise<void>}
 */
const handleFunctionSubmit = async () => {
  try {
    await functionFormRef.value.validate()

    const isEdit = !!functionForm.id
    const functionData = {
      ...functionForm,
      pid: selectedMenuId.value // 关联当前选中的菜单
    }

    const apiCall = isEdit
      ? menuApi.updateFunction(functionData)
      : menuApi.createFunction(functionData)

    await apiCall
    ElMessage.success(isEdit ? '编辑成功' : '新增成功')
    functionDialogVisible.value = false

    // 重新加载功能列表
    await loadFunctionList(selectedMenuId.value)
  } catch (error) {
    if (error.message) {
      console.error('功能操作失败:', error)
      ElMessage.error(error.message || '操作失败')
    } else {
      console.error('表单验证失败:', error)
    }
  }
}

/**
 * 重置菜单表单
 * 将菜单表单重置为初始状态并清除验证状态
 * @function resetMenuForm
 * @returns {void}
 */
const resetMenuForm = () => {
  Object.assign(menuForm, {
    menu_name: '',
    menu_url: '',
    pid: '0',
    menu_icon: '',
    orderid: 1,
  })
  menuFormRef.value?.clearValidate()
}

/**
 * 重置功能表单
 * 将功能表单重置为初始状态并清除验证状态
 * @function resetFunctionForm
 * @returns {void}
 */
const resetFunctionForm = () => {
  Object.assign(functionForm, {
    menu_name: '',
    menu_url: '',
    pid: '0',
    menu_icon: '',
    orderid: 1,
  })
  functionFormRef.value?.clearValidate()
}

/**
 * 组件挂载生命周期钩子
 * 组件挂载完成后初始化页面数据
 */
onMounted(() => {
  initData()
})
</script>

<style scoped>
.menu-management {
  background-color: #f5f7fa;
  padding: 0;
  overflow: hidden;
  height: 100%;
}

.menu-container {
  display: flex;
  height: 100%;
  gap: 0;
}

/* 左侧菜单树样式 */
.menu-tree-panel {
  width: 220px;
  background: white;
  border-right: 1px solid #e4e7ed;
  display: flex;
  flex-direction: column;
}

.el-button+.el-button {
  margin: 0;
}

.panel-header {
  height: 50px;
  background: var(--theme-primary);
  color: white;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 15px;
  font-weight: 500;
  border-bottom: 1px solid #e4e7ed;
}

.header-title {
  font-size: 14px;
  font-weight: 500;
}

.tree-content {
  flex: 1;
  overflow: auto;
  padding: 0;
}

/* 树形组件样式 */
.menu-tree {
  background: transparent;
  font-size: 14px;
}

.menu-tree :deep(.el-tree-node) {
  margin-bottom: 0;
}

.menu-tree :deep(.el-tree-node__content) {
  padding: 0 8px;
  border-radius: 0;
  transition: all 0.2s;
}

:deep(.menu-tree .el-tree-node__expand-icon) {
  color: #666 !important;
  visibility: inherit;
}

.menu-tree :deep(.el-tree-node__content:hover) {
  background-color: #f5f7fa;
}

.menu-tree :deep(.el-tree-node.is-current > .el-tree-node__content) {
  background-color: #e8f4fd;
  color: #4a90e2;
}

.menu-tree :deep(.el-tree-node__expand-icon) {
  color: #c0c4cc;
  font-size: 12px;
  margin-right: 4px;
}

.menu-tree :deep(.el-tree-node__expand-icon.is-leaf) {
  color: transparent;
}

.menu-tree :deep(.el-tree-node__label) {
  font-size: 12px;
  color: #606266;
}

.menu-tree :deep(.el-tree-node.is-current .el-tree-node__label) {
  color: #4a90e2;
  font-weight: 500;
}

/* 树节点内容样式 */
.tree-node {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  font-size: 12px;
}

.node-content {
  display: flex;
  align-items: center;
  flex: 1;
}

.node-label {
  font-size: 13px;
  color: #606266;
  margin-right: 6px;
}

.status-disabled {
  font-size: 11px;
  color: var(--theme-danger);
  background-color: var(--theme-danger-lighter);
  padding: 1px 4px;
  border-radius: 2px;
}





.action-btn {
  padding: 2px 4px;
  color: #909399;
  border: none;
  background: none;
  border-radius: 2px;
  font-size: 12px;
}

.action-btn:hover {
  color: var(--theme-primary);
  background-color: var(--theme-primary-lighter);
}

.delete-btn:hover {
  color: var(--theme-danger);
  background-color: var(--theme-danger-lighter);
}

/* 右侧表格样式 */
.function-table-panel {
  flex: 1;
  background: white;
  display: flex;
  flex-direction: column;
}

.table-content {
  flex: 1;
  overflow: hidden;
  padding: 10px;
  position: relative;
}

/* 表格样式已移至公共样式文件 */



/* 表格操作按钮 */
.table-action-btn {
  margin: 0 2px;
  padding: 2px 8px;
  font-size: 12px;
  border: none;
  background: none;
}

.edit-btn {
  color: var(--theme-primary);
}

.edit-btn:hover {
  background-color: #f0f9ff;
  color: #4a90e2;
}

.table-action-btn.delete-btn {
  color: #f56c6c;
}

.table-action-btn.delete-btn:hover {
  background-color: #fef0f0;
  color: #f56c6c;
}

/* 对话框样式 */
.dialog-footer {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
}

/* 自定义滚动条 */
.tree-content::-webkit-scrollbar,
.table-wrapper::-webkit-scrollbar {
  width: 6px;
}

.tree-content::-webkit-scrollbar-track,
.table-wrapper::-webkit-scrollbar-track {
  background: #f1f1f1;
  border-radius: 3px;
}

.tree-content::-webkit-scrollbar-thumb,
.table-wrapper::-webkit-scrollbar-thumb {
  background: #c1c1c1;
  border-radius: 3px;
}

.tree-content::-webkit-scrollbar-thumb:hover,
.table-wrapper::-webkit-scrollbar-thumb:hover {
  background: #a8a8a8;
}
</style>